// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.chimi.service.impl;

import com.liuxinlong.common.AosException;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.chimi.dto.BarLuckAudienceDto;
import com.liuxinlong.modules.chimi.dto.BarLuckAwardDto;
import com.liuxinlong.modules.chimi.service.BarLuckDetailService;
import com.liuxinlong.modules.dao.BarLuckAudienceDao;
import com.liuxinlong.modules.dao.BarLuckAwardDao;
import com.liuxinlong.modules.dao.BarLuckDao;
import com.liuxinlong.modules.dao.BarLuckFlowDao;
import com.liuxinlong.modules.dao.BarPresentDao;
import com.liuxinlong.modules.dao.BarPresentFlowDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.entity.BarLuck;
import com.liuxinlong.modules.entity.BarLuckAudience;
import com.liuxinlong.modules.entity.BarLuckAward;
import com.liuxinlong.modules.entity.User;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.ThreadlocalUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 论坛抽奖管理服务层接口实现
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022-08-08
 */
@Service
@Slf4j
public class BarLuckDetailServiceImpl implements BarLuckDetailService {
    @Autowired
    private BarLuckDao barLuckDao;

    @Autowired
    private BarLuckAwardDao barLuckAwardDao;

    @Autowired
    private BarLuckAudienceDao barLuckAudienceDao;

    @Autowired
    private BarPresentDao barPresentDao;

    @Autowired
    private BarPresentFlowDao barPresentFlowDao;

    @Autowired
    private BarLuckFlowDao barLuckFlowDao;

    @Autowired
    private UserDao userDao;

    @Override
    public List<Map<String, Object>> pageLuckAwardList(Map<String, Object> queryParam) {
        int startNum = (int) queryParam.get("startNum");
        List<BarLuckAward> awardList = barLuckAwardDao.pageBarLuckAwardList(queryParam);
        return completeAwardResult(awardList, startNum);
    }

    @Override
    public int getLuckAwardCount(Map<String, Object> queryParam) {
        return barLuckAwardDao.getBarLuckAwardCount(queryParam);
    }

    @Override
    public void updateLuckAward(String luckId, List<BarLuckAwardDto> barLuckAwardList) {
        BarLuck barLuck = barLuckDao.selectById(luckId);
        if (ObjectUtils.isEmpty(barLuck)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改失败,抽奖活动不存在！");
        }
        if (barLuck.getStatus() == 1) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改失败，抽奖活动已生效！");
        }
        List<BarLuckAward> awardList = new ArrayList<>();
        barLuckAwardDao.deleteByLuckId(luckId);
        for (BarLuckAwardDto dto : barLuckAwardList) {
            BarLuckAward award = new BarLuckAward();
            award.setId(SnowFlake.nextIdStr());
            award.setLuckId(luckId);
            award.setPresentId(dto.getPresentId());
            award.setSortNum(dto.getSortNum());
            award.setMaxNum(dto.getMaxNum());
            award.setNum(dto.getNum());
            award.setLeftNum(dto.getNum());
            award.setWinningRate(dto.getWinningRate());
            awardList.add(award);
        }
        if (ObjectUtils.isEmpty(barLuckAwardList)) {
            return;
        }
        barLuckAwardDao.insertBatch(awardList);
    }

    @Override
    public List<Map<String, Object>> pageLuckAudienceList(Map<String, Object> queryParam) {
        int startNum = (int) queryParam.get("startNum");
        List<BarLuckAudience> audienceList = barLuckAudienceDao.pageBarLuckAudienceList(queryParam);
        return completeAudienceResult(audienceList, startNum);
    }

    @Override
    public int getLuckAudienceCount(Map<String, Object> queryParam) {
        return barLuckAudienceDao.getBarLuckAudienceCount(queryParam);
    }

    @Override
    public void updateLuckAudience(String luckId, List<BarLuckAudienceDto> barLuckAudienceList) {
        BarLuck barLuck = barLuckDao.selectById(luckId);
        if (ObjectUtils.isEmpty(barLuck)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改失败,抽奖活动不存在！");
        }
        if (barLuck.getStatus() == 1) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "修改失败，抽奖活动已生效！");
        }
        List<BarLuckAudience> audienceList = new ArrayList<>();
        barLuckAudienceDao.deleteByLuckId(luckId);
        for (BarLuckAudienceDto dto : barLuckAudienceList) {
            BarLuckAudience audience = new BarLuckAudience();
            audience.setId(SnowFlake.nextIdStr());
            audience.setLuckId(luckId);
            audience.setUserId(dto.getUserId());
            audience.setMaxNum(dto.getMaxNum());
            audience.setWinningRate(dto.getWinningRate());
            audienceList.add(audience);
        }
        if (ObjectUtils.isEmpty(audienceList)) {
            return;
        }
        barLuckAudienceDao.insertBatch(audienceList);
    }

    @Override
    public Map<String, Object> queryParticipationTime(String userId,String luckId) {
        Map<String, Object> resultMap = new HashMap<>();
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        BarLuck barLuck;
        if (StringUtils.isNotEmpty(luckId)) {
            barLuck = barLuckDao.selectById(luckId);
            if (barLuck.getStatus() != 1) {
                log.info("暂无可用活动");
                return resultMap;
            }
        } else {
            List<BarLuck> effectiveList = barLuckDao.queryEffectiveLuck(currentTime);
            if (ObjectUtils.isEmpty(effectiveList)) {
                log.info("暂无可用活动");
                return resultMap;
            }
            barLuck = effectiveList.get(0);
        }
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put("luckId", barLuck.getId());
        int hisAccessNum = barPresentFlowDao.getBarPresentFlowCount(queryParam);
        if (!(barLuck.getTotalNum() > hisAccessNum)) {
            log.info("活动剩余奖品数不足");
            return resultMap;
        }
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        queryParam.put("userId", currentUser.getId());
        if (barLuck.getDelivery() == 1 && ObjectUtils.isEmpty(barLuckAudienceDao.getBarLuckOpportunity(barLuck.getId(), currentUser.getId()))) {
            log.info("用户不具备活动参与权限！");
            return resultMap;
        }

        // 获取用户参与次数
        int leftTime = 0;
        if (barLuck.getDailyType() == 1 ) {
            queryParam.put("operateDate", TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD));
            int userCurrentTime = barLuckFlowDao.getUserCurrentDayCount(queryParam);
            leftTime = barLuck.getDailyMaxTime() - userCurrentTime;
            if (!(userCurrentTime < barLuck.getDailyMaxTime())) {
                log.info("超过活动最大参与次数！");
                return resultMap;
            }
        } else {
            int userJoinTime = barLuckFlowDao.getUserCurrentDayCount(queryParam);
            leftTime = barLuck.getDailyMaxTime() - userJoinTime;
            if (!(userJoinTime < barLuck.getTotalMaxTime())) {
                log.info("超过活动最大参与次数！");
                return resultMap;
            }
        }
        resultMap.put("luckId", barLuck.getId());
//        resultMap.put();
        resultMap.put("time", leftTime);
        return resultMap;
    }

    /**
     * 数据补全转换
     *
     * @param originList 原始数据列表
     * @param startNum   起始查询数
     * @return 补全数据
     */
    private List<Map<String, Object>> completeAwardResult(List<BarLuckAward> originList, int startNum) {
        if (ObjectUtils.isEmpty(originList)) {
            return new ArrayList<>();
        }
        List<Map<String, Object>> resultList = new ArrayList<>(originList.size());
        Map<String,Map<String,String>> presentMap = barPresentDao.queryPresentMap();
        int sort = startNum + 1;
        for (BarLuckAward award : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(award);
            map.put("sort", sort);
            map.put("presentName", presentMap.containsKey(award.getPresentId()) ? presentMap.get(award.getPresentId()).get("name") : "-");
            resultList.add(map);
            sort++;
        }
        return resultList;
    }

    /**
     * 数据补全转换
     *
     * @param originList 原始数据列表
     * @param startNum   起始查询数
     * @return 补全数据
     */
    private List<Map<String, Object>> completeAudienceResult(List<BarLuckAudience> originList, int startNum) {
        if (ObjectUtils.isEmpty(originList)) {
            return new ArrayList<>();
        }
        List<Map<String, Object>> resultList = new ArrayList<>(originList.size());
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
        int sort = startNum + 1;
        for (BarLuckAudience audience : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(audience);
            map.put("sort", sort);
            if (userMap.containsKey(audience.getUserId())) {
                map.put("name", userMap.get(audience.getUserId()).get("name"));
            }
            resultList.add(map);
            sort++;
        }
        return resultList;
    }
}
